import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:karyo/karyo.dart';
import 'package:karyo/src/app_utils.dart';
import 'package:karyo/src/models/user.dart';
import 'package:karyo/src/models/user_mana.dart';
import 'dart:async';

import 'api_constants.dart';

class CommonAPIClient {
  var dio = CommonAPIClient.createDio();

  static Dio createDio() {
    var options = BaseOptions(
      baseUrl: API.BASE_URL,
      connectTimeout: 10000,
      receiveTimeout: 100000,
      contentType: "json",
    );
    return Dio(options);
  }



  // MANA platform
  Future<ManaUser> getMANAUser(String token) async {
    var _url = '${API.MANA_USERS_URL}?token=$token';
    http.Response response = await http.get(Uri.parse(_url));
    var rpJson = json.decode(response.body);
    print(rpJson);
    if (rpJson['status'] == 'success') {
      var _u = ManaUser.fromMap(rpJson['data']);
      return _u;
    } else {
      return null;
    }
  }

  Future<ManaUser> getManaUserByEmail(String e, String token) async {
    var _url = '${API.SEARCH_MANA_USER}?user_email=${e}&token=$token';
    http.Response response = await http.get(Uri.parse(_url));
    var rpJson = json.decode(response.body);
    print(rpJson);
    if (rpJson['status'] == 'success' && rpJson['data'].length > 0) {
      var _u = ManaUser.fromMap(rpJson['data']);
      return _u;
    } else {
      return null;
    }
  }

 
  Future<List<ManaUser>> getAllUsersMana(
      String token, int pageNum, int perPage) async {
    http.Response response = await http.get(
        Uri.parse('${API.MANA_USERS_GET}?page_num=${pageNum}&per_page=$perPage&token=$token'));
    var rp = utf8.decode(response.bodyBytes);
    var rpJson = json.decode(rp);

    if (rpJson['status'] == 'success') {
      var _allUsers = ManaUser.allFromResponse(rp);
      return _allUsers;
    } else {
      print('get mana all users fail----- $rpJson');
      return null;
    }
  }

  Future<bool> setUserManaVip(ManaUser user, String act, String token) async {
    http.Response response = await http.get(
        Uri.parse('${API.SET_MANA_VIP}?act=${act}&user_id=${user.userID}&token=$token'));
    var rp = utf8.decode(response.bodyBytes);
    // get the response
    var rpJson = json.decode(rp);
    if (rpJson['status'] == 'success') {
      var msg = rpJson['message'];
      var isManaVIP = rpJson['data'];
      print(isManaVIP);
    } else {
      print(rpJson);
      var msg = rpJson['message'];
    }
    return true;
  }

  Future<List<User>> getAllUsersUranus(
      String token, int pageNum, int perPage) async {
    http.Response response = await http.get(
        Uri.parse('${API.GET_ALL_USERS_URANUS}?token=$token&page_num=$pageNum&per_page=$perPage'));
    var rp = utf8.decode(response.bodyBytes);
    var rpJson = json.decode(rp);
    if (rpJson['status'] == 'success') {
      var _allUsers = User.allFromResponse(response.body);
      print(_allUsers[0].toString());
      return _allUsers;
    } else {
      print(rpJson);
      return null;
    }
  }
  /// MANA end
  
  
  Future<User> getUser(String token) async {
    http.Response response =
        await http.get(Uri.parse('${API.USERS_URL}?token=$token'));
    var rpJson = json.decode(response.body);
    if (rpJson['status'] == 'success') {
      var user = User.fromMap(rpJson['data']);
      return user;
    } else {
      return null;
    }
  }

  // update user info
  Future<User> updateUserInfo(
      User newUser, String token, BuildContext context) async {
    var _formData;
    if (newUser.selectedImgAvatar != null) {
      _formData = new FormData.fromMap({
        "user_nick_name": newUser.userNickName,
        'user_sign': newUser.userSign,
        'user_city': newUser.userCity,
        'user_birth': newUser.userBirth,
        'user_gender': newUser.userGender,
        'user_avatar':
            await MultipartFile.fromFile(newUser.selectedImgAvatar.path),
        'user_phone': '',
      });
      print(newUser.selectedImgAvatar);
    } else {
      _formData = new FormData.fromMap({
        "user_nick_name": newUser.userNickName,
        'user_sign': newUser.userSign,
        'user_city': newUser.userCity,
        'user_birth': newUser.userBirth,
        'user_gender': newUser.userGender,
        'user_phone': '',
      });
    }
    print(_formData);

    Dio dio = new Dio();
    Response response =
        await dio.post('${API.USERS_EDIT}?token=$token', data: _formData);
    var rpJson = response.data;
    if (rpJson['status'] == 'success') {
      print(rpJson['data']);
      print(rpJson['data']['user_avatar_url']);
      var _u = User.fromMap(rpJson['data']);
      // GlobalSettings.user =
      showToast(context, "修改成功，头像重启APP生效", COLOR_PRIMARY);
      return _u;
    } else {
      print('更新信息失败');
      showToast(context, "更新资料失败", COLOR_PRIMARY);
      return null;
    }
  }

  Future<User> login(
      String username, String password, BuildContext context) async {
    // call /api/v1/users_login api
    var _body = {"user_acc": username, "user_password": password};
    var response = await http.post(Uri.parse(API.LOGIN_URL), body: _body);
    print("Response status: ${response.statusCode}");
    var responseJson = json.decode(response.body);
    if (responseJson["status"] == "success") {
      var token = responseJson["data"]["token"];
      var u = User.fromMap(responseJson['data']);
      // print(token);
      GlobalSettings.user = u;
      SharedPreferenceUtil.save(SharedPreferenceUtil.KEY_TOKEN, token);
      showToast(context, "登录成功，欢迎 ${u.userNickName}", COLOR_PRIMARY);
      return u;
    } else {
      showToast(context, '登录失败，${username} ${password} ${responseJson['msg']}',
          COLOR_PRIMARY,
          icon: Icon(
            Icons.error,
            color: Colors.red,
          ));
      return null;
    }
  }

// search user
  Future<User> searchUser(String userAcc, String token) async {
    http.Response response = await http
        .get(Uri.parse('${API.FIND_USER}?token=$token&user_acc=$userAcc'));
    var rpJson = json.decode(response.body);
    if (rpJson['status'] == 'success') {
      var user = User.fromMap(rpJson['data']);
      return user;
    } else {
      return null;
    }
  }

  // register
  Future<User> register(
      String username, String password, BuildContext context) async {
    FormData _formData = new FormData.fromMap({
      "user_acc": username,
      "user_nick_name": 'Daybreak用户',
      'user_password': password,
    });

    Dio dio = new Dio();
    Response response = await dio.post(API.USERS_URL, data: _formData);
    var rpJson = response.data;
    if (rpJson['code'] == 200) {
      if (rpJson['status'] == 'success') {
        // login success, save values, and jump to home
        var _token = rpJson['data']['token'];
        var _userAddr = rpJson['data']['user_addr'];
        SharedPreferenceUtil.save(SharedPreferenceUtil.KEY_TOKEN, _token);
        showToast(context, "注册成功！你的登录帐号号为: $username", COLOR_PRIMARY);
      } else {
        showToast(context, "注册失败", COLOR_PRIMARY);
      }
    } else if (rpJson['code'] == 409) {
      showToast(context, "该帐号已经存在，请更换一个，如果这是您的帐号，请直接登录", COLOR_PRIMARY);
    } else {
      showToast(context, "登录失败： ${rpJson['msg']}", COLOR_PRIMARY);
    }
  }

  Future<User> registerWithInviteCode(String username, String password,
      String inviteCode, BuildContext context) async {
    FormData _formData = new FormData.fromMap({
      "user_acc": username,
      "user_nick_name": 'DB大玩家',
      'user_password': password,
      "invite_code": inviteCode,
    });

    Dio dio = new Dio();
    Response response = await dio.post(API.USERS2_URL, data: _formData);
    var rpJson = response.data;
    if (rpJson['code'] == 200) {
      if (rpJson['status'] == 'success') {
        // login success, save values, and jump to home
        var _token = rpJson['data']['token'];
        var _userAddr = rpJson['data']['user_addr'];
        SharedPreferenceUtil.save(SharedPreferenceUtil.KEY_TOKEN, _token);
        showToast(context, "注册成功！你的登录帐号号为: $username", COLOR_PRIMARY);
      } else {
        showToast(context, "注册失败", COLOR_PRIMARY);
      }
    } else if (rpJson['code'] == 409) {
      showToast(context, "该帐号已经存在，请更换一个，如果这是您的帐号，请直接登录", COLOR_PRIMARY);
    } else {
      showToast(context, "注册失败： ${rpJson['msg']}", COLOR_PRIMARY);
    }
  }

  static request(String url, [Map<String, dynamic> params]) async {
    Dio dio = new Dio(new BaseOptions(responseType: ResponseType.json));
    Response response;
    if (params == null) {
      response = await dio.get(url);
    } else {
      response = await dio.get(url, queryParameters: params);
    }
    return response.data is String ? jsonDecode(response.data) : response.data;
  }
}


